package ffmpeg;

import encoder.RtmpAudioEncoder;
import encoder.RtmpVideoEncoder;
import rtmp.RtmpResponse;
import util.Common;
import util.MsgType;
import io.netty.channel.ChannelHandlerContext;
import org.apache.log4j.Logger;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.avutil;

public class EventDecoderRunnable implements Runnable{
    private final static Logger logger = Logger.getLogger(EventDecoderRunnable.class);
    private int chunkLength;
    private ChannelHandlerContext ctx;
    private FFmpeg ffmpeg;
    private int  diff = 10000;
    private int responseCheckLength = 0;
    private boolean isSeek = false; //进度条切换
    private boolean awaitKeyFrame = false; //等待关键帧
    private long time = 0;
    private boolean clearStatus = false;
    private int prevTime = 0;

    public void stop() {
        this.stop = true;
    }

    public void start(){
        this.stop = false;
    }

    private boolean stop = false;
    private String videoPath = "F:\\Work\\rustProject\\marvel-player\\test.mp4";

    public EventDecoderRunnable(ChannelHandlerContext ctx, int chunkLength, String videoPath) {
        this.chunkLength = chunkLength;
        this.ctx = ctx;
        this.videoPath = videoPath;
        ffmpeg  = new FFmpeg();
        ffmpeg.open(this.videoPath);
        sendHead();
    }

    public void setSeek(long time){
        stop = false;
        prevTime = (int) time;
        ffmpeg.seekFrame(time);
        sendHead();
    }

    private void sendVideoHead(){
        SpsPpsInfo spsPpsInfo = ffmpeg.parseSpsPps();
        byte[] data = RtmpVideoEncoder.encoderSPSPPS(spsPpsInfo.getSps(), spsPpsInfo.getPps());
        responseCheckLength += data.length;
        RtmpResponse.sendData(data,
                MsgType.MSG_VIDEO, 1337, ctx, 0, chunkLength);
    }

    private void sendAudioHead(){
        byte[] data = RtmpAudioEncoder.encoderAdts(ffmpeg.getExtradata(ffmpeg.getAvStreamIndex().getAudioStreamIndex()));
        responseCheckLength += data.length;
        RtmpResponse.sendData(data,
                MsgType.MSG_AUDIO, 1337, ctx, 0, chunkLength);
    }

    private void sendHead(){
        sendVideoHead();
        sendAudioHead();
    }

    @Override
    public void run() {
        try{
            int time = 0;
            int index = 0;
//            while (time - prevTime < 5 * 1000){ //10秒
                while (index++ < 100){ //10秒
                if(stop) break;
                avcodec.AVPacket avPacket = ffmpeg.getAvPacket();
                if (avPacket != null) {
                    avutil.AVRational avRational = ffmpeg.getAvFormatContext().streams(avPacket.stream_index()).time_base();
                    double timeBase = (1000.0*ffmpeg.r2d(avRational));
                    time = (int) (avPacket.pts() * timeBase);
                    responseCheckLength += avPacket.size();
                    if (avPacket.stream_index() == ffmpeg.getAvStreamIndex().getVideoStreamIndex()) {
                        byte[] data = new byte[avPacket.size()];
                        avPacket.data().get(data);
                        RtmpResponse.sendData(RtmpVideoEncoder.encoderBody(data, avPacket.flags()),
                                MsgType.MSG_VIDEO, 1337, ctx, time, chunkLength);


                    } else if (avPacket.stream_index() == ffmpeg.getAvStreamIndex().getAudioStreamIndex()) {
                        byte[] audioData = new byte[avPacket.size()];
                        avPacket.data().get(audioData);
                        RtmpResponse.sendData(RtmpAudioEncoder.encoderData(audioData),
                                MsgType.MSG_AUDIO, 1337, ctx, time, chunkLength);
                    }
                } else {
                    break;
                }
            }
            prevTime = time;
        }catch (Exception e) {
            e.printStackTrace();
        }
    }



    public int getResponseCheckLength() {
        return responseCheckLength;
    }

    public int getDiff() {
        return diff;
    }
}
